# Copyright 2012 by IBM
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
# Refer to the README and COPYING files for full details of the license
#

import os
import pwd
import shutil
import subprocess

from vdsm.tool import expose

try:
    from ovirtnode import ovirtfunctions
except ImportError:
    pass


EX_OPENSSL = '/usr/bin/openssl'

PATH_CERT = '/etc/pki/vdsm/certs/'
PATH_CACERT = PATH_CERT + 'cacert.pem'
PATH_VDSMCERT = PATH_CERT + 'vdsmcert.pem'


def is_our_cafile(cacert):
    cmd = [EX_OPENSSL, 'verify', '-CAfile', cacert, PATH_VDSMCERT]
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out = p.communicate()[0]
    return out.rstrip('\n') == '%s: OK' % PATH_VDSMCERT


@expose('validate-ovirt-certs')
def validate_ovirt_certs():
    """
    Validate vdsmcert.pem against cacert.pem.
    If current cacert.pem is invalidate, it will find a validate certificate
    file and replace the old cacert.pem with it. And then persist it.
    """
    print "checking certs.."
    uid, gid = pwd.getpwnam('vdsm')[2:4]
    if not is_our_cafile(PATH_CACERT):
        for f in os.listdir(PATH_CERT):
            if is_our_cafile(PATH_CERT + f):
                ovirtfunctions.ovirt_safe_delete_config(PATH_CACERT)
                shutil.copy(PATH_CERT + f, PATH_CACERT)
                os.chown(PATH_CACERT, uid, gid)
                ovirtfunctions.ovirt_store_config(PATH_CACERT)
                break
